package ihm;

import job.Controler;
import job.Drawer;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;

/**
 * Classe repr�sentant le contenu de la fen�tre principale de notre jeu de Tetris
 * @author Laurent et Flav
 */
public class Content extends JPanel implements ActionListener, Drawer {
	private static final long serialVersionUID = 1054963435588632990L;
	
	public static final int BLOCKSIZE = 18;
	protected static Window mainWindow = null;
	public boolean startGame = false;
	
	/** El�ments affich�s par notre fen�tre */
	protected static JLabel messageLabel = new JLabel();
	protected static JLabel gameLabel = new JLabel();
	protected static JMenuBar menu = new JMenuBar();
	protected static JMenu edit;
	protected static JMenuItem preferences;
	protected static JMenu file;
	protected static JMenuItem newPart;
	protected static JMenuItem exit;
	protected static JMenu other;
	protected static JMenuItem help;
	protected static JMenuItem about;
	protected static JFrame frame = new JFrame("Options");
	protected static JPanel panel = new JPanel();
	protected static JButton ok = new JButton("OK");
	protected static DefaultListModel timer = new DefaultListModel();
	protected static JList list = new JList(timer);
	
	/** Dimensions par d�faut de notre terrain de jeu */
	private int widthP = 190;
	private int heightP = 400;
	
	/** Abscisse par d�faut du centre du rep�re en pixels */
	private int X0 = 0;
	/** Ordonn�e par d�faut du centre du rep�re en pixels */
	private int Y0 = 0;
	
	/** Tableaux contenant les abscisses et les ordonn�es de nos blocs pr�sents dans le terrain */
	protected ArrayList<Integer> x_block = new ArrayList<Integer>(widthP * heightP / (BLOCKSIZE * BLOCKSIZE));
	protected ArrayList<Integer> y_block = new ArrayList<Integer>(widthP * heightP / (BLOCKSIZE * BLOCKSIZE));
	protected ArrayList<Integer> c_block = new ArrayList<Integer>(widthP * heightP / (BLOCKSIZE * BLOCKSIZE));
	public Listener myListener;
	
	/**
	 * Constructeur par d�faut
	 * Cr�e les �l�ments qu'il faut afficher dans notre fen�tre
	 */
	public Content(Window mainWindow){
		setLayout(new BorderLayout());
		setBackground(Color.WHITE);
	
		myListener = new Listener();
		this.mainWindow = mainWindow;
		
		/** Cr�ation du menu */
		this.file = new JMenu("Fichier");
		this.newPart = new JMenuItem("Nouvelle Partie", KeyEvent.VK_P);
		this.newPart.addActionListener(this);
		this.exit = new JMenuItem("Quitter");
		this.exit.addActionListener(myListener);
		this.file.add(this.newPart);
		this.file.add(this.exit);
		this.menu.add(this.file);
		
		this.edit = new JMenu("Edition");
		this.preferences = new JMenuItem("Pr�f�rences");
		this.preferences.addActionListener(myListener);
		this.edit.add(this.preferences);
		this.menu.add(this.edit);
		
		this.other = new JMenu("?");
		this.help = new JMenuItem("Aide");
		this.help.addActionListener(myListener);
		this.about = new JMenuItem("A propos de...");
		this.about.addActionListener(myListener);
		this.other.add(this.help);
		this.other.add(this.about);
		this.menu.add(this.other);

		/** Ajoute le panel de message */
		//this.add(this.messageLabel);
		add(this.messageLabel);
		 
		add(this.menu, BorderLayout.NORTH);
	}
	
	/**
	 * Fixe les dimensions de notre terrain de jeu
	 * @param x Largeur de notre terrain en pixels
	 * @param y Hauteur de notre terrain en pixels
	 */
	public void setPlayGroundDimensions(int x, int y){
		this.widthP = x*BLOCKSIZE;
		this.heightP = (y+1)*BLOCKSIZE;
		this.Y0 = heightP;
	}
	
	/** Comme drawBlockAtPosition mais pour la piece suivante */
	public void drawNextPieceBlock(int x, int y, int color) {
		x_block.add(x + widthP/BLOCKSIZE + 2);
		y_block.add(y + heightP/BLOCKSIZE - 5);
		c_block.add(color);
		repaint();
	}
	
	/**
	 * Ajoute l'abscisse et l'ordonn�e d'un bloc � nos tableaux
	 * @param x Abscisse du bloc � afficher dans le terrain, unit� : bloc
	 * @param y Ordonn�e du bloc � afficher dans le terrain, unit� : bloc
	 */
	public void drawBlockAtPosition(int x, int y, int color){
		this.x_block.add(x);
		this.y_block.add(y);
		this.c_block.add(color);
		repaint();
	}
	
	/** Efface les blocks */
	public void clear() {
		this.x_block.clear();
		this.y_block.clear();
		this.c_block.clear();
	}
	
	
	/**
	 * Dessine l'ensemble de nos blocs dans le terrain
	 * @param g
	 * @param start
	 */
	public void paint(Graphics g, int start) {
	}
	
	/**	
	 * Affiche toute la grille et positionne les blocs
	 * @param g
	 */
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		g.fillRect(0,0,this.widthP,this.heightP);
		for(int i = 0; i < x_block.size(); i++){
			switch(this.c_block.get(i)) {
			case 0:
				drawBlock(this.x_block.get(i), this.y_block.get(i), Color.RED, g);
				break;
			case 1:
				drawBlock(this.x_block.get(i), this.y_block.get(i), Color.BLUE, g);
				break;
			case 2:
				drawBlock(this.x_block.get(i), this.y_block.get(i), Color.YELLOW, g);
				break;
			case 3:
				drawBlock(this.x_block.get(i), this.y_block.get(i), Color.GREEN, g);
				break;
			case 4:
				drawBlock(this.x_block.get(i), this.y_block.get(i), Color.GRAY, g);
				break;
			case 5:
				drawBlock(this.x_block.get(i), this.y_block.get(i), Color.MAGENTA, g);
				break;
			case 6:
				drawBlock(this.x_block.get(i), this.y_block.get(i), Color.PINK, g);
				break;
			}
		}
		this.messageLabel.setLocation(widthP+10,0);
	}
		

	
	/**
	 * Cr�ation d'un bloc
	 * @param x abscisse du bloc, unit� : bloc
	 * @param y ordonn�e du bloc, unit� : bloc
	 * @param c couleur du bloc
	 * @param g
	 */
	public void drawBlock(int x, int y, Color c, Graphics g){
		g.setColor(c);
		g.drawRect(this.X0+x*BLOCKSIZE,this.Y0-(y+1)*BLOCKSIZE,BLOCKSIZE-2,BLOCKSIZE-2);
		g.fillRect(this.X0+x*BLOCKSIZE+2,this.Y0-(y+1)*BLOCKSIZE+2,BLOCKSIZE-2,BLOCKSIZE-2);
	}
	
	public void setEventListener(Controler e) {
		this.setFocusable(true);
		this.addKeyListener((KeyListener)e);
	}
	
	/** demande une nouvelle partie */
	public boolean requestNewGame() {
		if(startGame) {
			messageLabel.setText("");
			startGame = false;
			return true;
		}
		return false;
	}
	
	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == Content.newPart){
			startGame = true;
		}
	}
	
	/** Dessine le message de fin de jeu */
	public void drawGameOver() {
		messageLabel.setText("GAME OVER");
	}
	
	/** Dessine le score */
	public void drawScore(int nbLines, int nbPoints, int lvl) {
		messageLabel.setText("<html>Niveau : "+lvl+
				"<br />Nombre de ligne : "+nbLines+
				"<br />Nombre de points : "+nbPoints+
				"</html>");
	}
}
